home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / RLE_SPR.ZIP / RLE_SPR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-02  |  8.4 KB  |  332 lines

  1. //////////////////////////////////////////////////////////////////////////////
  2. // Routines for load/save RLE compressed sprite files
  3. // Copyright 1997 Aleksei Sujurov
  4. //////////////////////////////////////////////////////////////////////////////
  5.  
  6. // I N C L U D E /////////////////////////////////////////////////////////////
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <conio.h>
  12. #include <wgt5.h>
  13.  
  14. #include "rle_spr.h"
  15.  
  16. // D E F I N E S   ///////////////////////////////////////////////////////////
  17.  
  18. #define         NORMAL          0
  19. #define         RLE             1
  20. #define         MAX_SPR         2000
  21.  
  22. // P R O T O T Y P E S ///////////////////////////////////////////////////////
  23.  
  24. static int EncodeRun(int val, int run_length, FILE * file);
  25. static int EncodeSprite (FILE * file,
  26.                         block line_buffer,
  27.                         unsigned int length);
  28. static int DecodeSprite (FILE* file, block line_buffer, unsigned int length);
  29.  
  30. // F U N C T I O N S ////////////////////////////////////////////////////////
  31.  
  32. short  wloadsprites_rle (color *pal, char *filename, block *image_array,
  33.                      short start, short end)
  34. {
  35.         short  i, a;
  36.         short  maxspr;
  37.         short  made;
  38.         short  width, height;
  39.         char   buf[20];
  40.         long   size;
  41.  
  42.         if  (wgtlibrary == NULL)
  43.         {
  44.             if  ((libf = fopen (filename, "rb")) == NULL)
  45.             {
  46.                 return (-1);
  47.             }
  48.         }
  49.         else
  50.         {
  51.             if  ((libf = fopen (wgtlibrary, "rb")) == NULL)
  52.             {
  53.                 return (-1);
  54.             }
  55.             readheader ();
  56.             findfile (filename);
  57.             if (lresult == 1)
  58.                fseek (libf, lfpos, SEEK_SET);
  59.             if (checkpassword (password) == 0)
  60.             {
  61.               wsetmode (3);
  62.               fprintf (stderr, "Incorrect password\n");
  63.               exit (-1);
  64.             }
  65.         }
  66.  
  67.         fread (&a, 2, 1, libf);
  68.         if (a!=1)
  69.         {
  70.            return (-1);
  71.         }
  72.  
  73.         fread (buf, 17, 1, libf);
  74.         if (strnicmp (" RLE Sprite File ", buf, 17)!=0)
  75.         {
  76.            return (-1);
  77.         }
  78.  
  79.         fread (pal, 768, 1, libf);
  80.         fread (&maxspr, 2, 1, libf);
  81.  
  82.         if (maxspr>MAX_SPR)
  83.            maxspr=MAX_SPR;
  84.  
  85.         if (end>maxspr)
  86.            end=maxspr;
  87.  
  88.         if (start<0)
  89.            start=0;
  90.  
  91.         for (i=0; i<=end; i++)
  92.         {
  93.  
  94.             fread (&made, 2, 1, libf);
  95.  
  96.             if (made==1)
  97.             {
  98.                 fread (&width, 2, 1, libf);
  99.                 fread (&height, 2, 1, libf);
  100.                 fread (&size, 4, 1, libf);
  101.  
  102.                 if (i>=start)
  103.                 {
  104.                         if ((image_array[i]=(block) malloc (width*height+4))==NULL)
  105.                         {
  106.                                 return (-1);
  107.                         }
  108.                         fseek (libf, -8, SEEK_CUR);
  109.                         fread (image_array[i], 4, 1, libf);
  110.                         fseek (libf, 4, SEEK_CUR);
  111.  
  112.                         if (DecodeSprite (libf, image_array[i]+4, width*height))
  113.                         {
  114.                             fclose (libf);
  115.                             return (-1);
  116.  
  117.                         }
  118.                 }
  119.                 else
  120.                     fseek (libf, size, SEEK_CUR);
  121.             }
  122.  
  123.             if (i>=start)
  124.                if (!made)
  125.                   image_array[i]=NULL;
  126.  
  127.         }
  128.  
  129.         fclose (libf);
  130.  
  131.         return (0);
  132. }
  133.  
  134. //////////////////////////////////////////////////////////////////////////////
  135.  
  136. short  wsavesprites_rle (color *pal, char *filename, block *image_array,
  137.                      short start, short end)
  138. {
  139.  
  140.         FILE*  fp;
  141.         short i;
  142.  
  143.         short  version=0x01;
  144.         char   name[]=" RLE Sprite File ";
  145.         short  maxspr=MAX_SPR;
  146.  
  147.         short  made;
  148.         short  width, height;
  149.         fpos_t fpos1, fpos2;
  150.         long   size;
  151.  
  152.  
  153.         if ((fp=fopen (filename, "wb"))==NULL)
  154.         {
  155.            return (-1);
  156.         }
  157.  
  158.         fwrite (&version, sizeof (short), 1, fp);
  159.         fputs  (name, fp);
  160.         fwrite (pal, 768, 1, fp);
  161.  
  162.         for (i=end; i>=start; i--)
  163.         {
  164.              if (image_array[i]!=NULL){
  165.                 maxspr=i;
  166.                 break;
  167.              }
  168.         }
  169.  
  170.         if (maxspr>MAX_SPR)
  171.            maxspr=MAX_SPR;
  172.  
  173.         if (end>maxspr)
  174.            end=maxspr;
  175.  
  176.         if (start<0)
  177.            start=0;
  178.  
  179.         fwrite (&end, sizeof (short), 1, fp);
  180.  
  181.         for (i=start; i<=end; i++)
  182.         {
  183.  
  184.             if (image_array[i]!=NULL)
  185.                made=1;
  186.             else
  187.                made=0;
  188.  
  189.             fwrite (&made, sizeof (short), 1, fp);
  190.  
  191.             if (made)
  192.             {
  193.                 width=wgetblockwidth (image_array[i]);
  194.                 height=wgetblockheight (image_array[i]);
  195.  
  196.                 fwrite (&width, sizeof (short), 1, fp);
  197.                 fwrite (&height, sizeof (short), 1, fp);
  198.  
  199.                 fgetpos (fp, &fpos1);
  200.                 fseek (fp, sizeof (long), SEEK_CUR);
  201.  
  202.                 if (EncodeSprite (fp, image_array[i]+4, width*height))
  203.                 {
  204.                         fclose (fp);
  205.                         return (-1);
  206.                 }
  207.  
  208.                 fgetpos (fp, &fpos2);
  209.                 size=fpos2-fpos1;
  210.                 fsetpos (fp, &fpos1);
  211.                 fwrite (&size, sizeof (long), 1, fp);
  212.                 fsetpos (fp, &fpos2);
  213.  
  214.             }
  215.  
  216.         }
  217.  
  218.         fclose (fp);
  219.         return (0);
  220.  
  221. }
  222.  
  223. //////////////////////////////////////////////////////////////////////////////
  224.  
  225. static int EncodeRun(int val, int run_length, FILE * file)
  226. {
  227.         if (run_length)
  228.         {
  229.                 if ((run_length == 1) && (0xC0 != (0xC0 & val)))
  230.                 {
  231.                      if (EOF == fputc(val, file))
  232.                         return (-1);
  233.                 }
  234.                 else
  235.                 {
  236.                      if (EOF == fputc(0xC0 | run_length, file))
  237.                         return (-1);
  238.  
  239.                      if (EOF == fputc(val, file))
  240.                         return (-1);
  241.                 }
  242.         }
  243.  
  244.     return (0);
  245.  
  246. }
  247.  
  248. //////////////////////////////////////////////////////////////////////////////
  249.  
  250. static int EncodeSprite (FILE * file,
  251.                          block line_buffer,
  252.                          unsigned int length)
  253. {
  254.     int oldval;
  255.     int newval;
  256.     int count;
  257.     unsigned length_counter;
  258.  
  259.     oldval = *line_buffer++;
  260.     length_counter = 1;
  261.     count = 1;
  262.  
  263.     while (length_counter < length)
  264.     {
  265.         newval = *line_buffer++;
  266.  
  267.         if (newval == oldval)
  268.         {
  269.                 count++;
  270.                 if (count == 63)
  271.                 {
  272.                        if (EncodeRun(oldval, count, file))
  273.                           return (-1);
  274.                        count = 0;
  275.                 }
  276.         }
  277.         else
  278.         {
  279.                 if (count)
  280.                    if (EncodeRun(oldval, count, file))
  281.                       return (-1);
  282.  
  283.                 oldval = newval;
  284.                 count = 1;
  285.         }
  286.  
  287.         length_counter++;
  288.  
  289.     }
  290.  
  291.     if (count)
  292.        if (EncodeRun(oldval, count, file))
  293.           return (-1);
  294.  
  295.         return (0);
  296. }
  297.  
  298. //////////////////////////////////////////////////////////////////////////////
  299.  
  300. static int DecodeSprite (FILE* file, block line_buffer, unsigned int length)
  301. {
  302.         unsigned int i;
  303.         short   mode=NORMAL;
  304.         short   nbytes;
  305.         char    abyte;
  306.  
  307.         for (i=0; i<length; i++)
  308.         {
  309.                 if (mode == NORMAL)
  310.                 {
  311.                         if ((abyte=fgetc(file))==EOF)
  312.                            return (-1);
  313.                         if ((unsigned char)abyte > 0xbf)
  314.                         {
  315.                                 nbytes=abyte & 0x3f;
  316.                                 if ((abyte=fgetc(file))==EOF)
  317.                                    return (-1);
  318.                                 if (--nbytes > 0)
  319.                                    mode=RLE;
  320.                         }
  321.                 }
  322.                 else
  323.                      if (--nbytes == 0)
  324.                         mode=NORMAL;
  325.  
  326.                 *line_buffer++=abyte;
  327.         }
  328.  
  329.         return (0);
  330.  
  331. }
  332.